﻿using AntdUI;
using AntdUI.Chat;
using SocketCore.Common.Config;
using SocketCore.Common.Event;
using SocketCore.Common.Message;
using SocketCore.Server;
using System.ComponentModel;

namespace WorkToolServer
{
    public partial class Main : Window
    {
        private readonly BindingList<UserClient> _userClients = [];
        private ServerManager _serverManager;
        private ServerConfig _serverConfig;
        private readonly Lock _lock = new();

        public Main()
        {
            InitializeComponent();
            user_table.Columns = [
                new ColumnCheck("Check").SetFixed().SetWidth("5%"),
                new Column("IPAddress", "IPAddress", ColumnAlign.Center).SetFixed().SetWidth("23%"),
                new Column("HostName", "HostName", ColumnAlign.Center).SetFixed().SetWidth("16%"),
                new Column("Version", "Version", ColumnAlign.Center).SetFixed().SetWidth("16%"),
                new Column("Action", "操作", ColumnAlign.Center).SetFixed().SetWidth("40%")
            ];
            user_table.Binding(_userClients);
        }

        protected override async void OnLoad(EventArgs e)
        {
            base.OnLoad(e);
            _serverConfig = new ServerConfig();
            _serverConfig.EventHub.OnEvent += (sender, e) =>
            {
                switch (e.Type)
                {
                    case SocketEventType.Log:
                        var logMessage = e.GetData<SocketLogMessage>();
                        if (!logMessage.Level.Equals(LogLevel.Debug))
                        {
                            chatList.Invoke(() =>
                            {
                                chatList.AddToBottom(new TextChatItem(logMessage.Message, null, $"Log [{e.DateTime:yyyy-MM-dd HH:mm:ss}]"));
                            });
                        }
                        if (check_debug.Checked && logMessage.Level.Equals(LogLevel.Debug))
                        {
                            chatList.Invoke(() =>
                            {
                                chatList.AddToBottom(new TextChatItem(logMessage.Message, null, $"Debug [{e.DateTime:yyyy-MM-dd HH:mm:ss}]").SetMe(false));
                            });
                        }
                        break;

                    case SocketEventType.Connect:
                        var connectMessage = e.GetData<SocketClientConnect>();
                        lock (_lock)
                        {
                            if (connectMessage.IsConnect)
                            {
                                if (!_userClients.Any(x => x.IPAddress.Equals(connectMessage.ClientInfo)))
                                {
                                    _userClients.Add(new UserClient { IPAddress = connectMessage.ClientInfo });
                                }
                            }
                            else
                            {
                                var userClient = _userClients.FirstOrDefault(x => x.IPAddress.Equals(connectMessage.ClientInfo));
                                if (userClient != null)
                                {
                                    _userClients.Remove(userClient);
                                }
                            }
                        }
                        break;

                    case SocketEventType.MessageReceived:
                        var receivedMessage = e.GetData<SocketClientMessage>();
                        chatList.Invoke(() =>
                        {
                            chatList.AddToBottom(new TextChatItem(receivedMessage.Message, null, $"{receivedMessage.ClientInfo} [{e.DateTime:yyyy-MM-dd HH:mm:ss}]"));
                        });
                        var messageData = receivedMessage.Message.Deserialize<MessageData<object>>();
                        switch (messageData.MessageDataType)
                        {
                            case MessageDataType.ClientVersion:
                                var clientVersion = receivedMessage.Message.Deserialize<MessageData<ClientVersionMessage>>();
                                var data = _userClients.FirstOrDefault(x => x.IPAddress.Equals(receivedMessage.ClientInfo));
                                if (data != null)
                                {
                                    data.Version = clientVersion.Data.Version;
                                    data.HostName = clientVersion.Data.HostName;
                                }
                                break;

                            default:
                                break;
                        }
                        break;

                    case SocketEventType.Heartbeat:
                        var heartbeatMessage = e.GetData<SocketHeartbeatMessage>();
                        if (check_heart.Checked)
                        {
                            chatList.Invoke(() =>
                            {
                                chatList.AddToBottom(new TextChatItem(heartbeatMessage.Message, null, $"Heartbeat [{e.DateTime:yyyy-MM-dd HH:mm:ss}]:"));
                            });
                        }
                        break;
                }
            };
            _serverManager = new ServerManager(_serverConfig);
            await _serverManager.StartAsync();
        }

        protected override void OnFormClosed(FormClosedEventArgs e)
        {
            _serverManager.Stop();
            base.OnFormClosed(e);
        }

        private async void table_CellButtonClick(object sender, TableButtonEventArgs e)
        {
            try
            {
                if (e.Record is UserClient data)
                {
                    switch (e.Btn.Id)
                    {
                        case "Dialog":
                            await _serverManager.SendAsync(data.IPAddress, new MessageData<string>() { MessageDataType = MessageDataType.Dialog, Data = "这是一个弹窗" }.Serialize());
                            break;

                        case "Notification":
                            await _serverManager.SendAsync(data.IPAddress, new MessageData<string>() { MessageDataType = MessageDataType.Notification, Data = "这是一个通知" }.Serialize());
                            break;

                        case "BetaUpdate":
                            await _serverManager.SendAsync(data.IPAddress, new MessageData<UpdateMessage>() { MessageDataType = MessageDataType.BetaUpdate, Data = new() { Version = "2.1.1.4", PublishDate = DateTime.Parse("2025-09-22"), Description = "内测更新", URL = "https://gitcode.com/gcw_E8NZtOkO/tools/releases/download/2.1.1.4/WorkTool.zip", UpdateVersion = "2.0.0.1", UpdateURL = "https://gitcode.com/gcw_E8NZtOkO/tools/releases/download/2.0.0.1/Update.zip" } }.Serialize());
                            break;

                        case "ForcedUpdate":
                            await _serverManager.SendAsync(data.IPAddress, new MessageData<UpdateMessage>() { MessageDataType = MessageDataType.ForcedUpdate, Data = new() { Version = "2.1.1.4", PublishDate = DateTime.Parse("2025-09-22"), Description = "强制更新", URL = "https://gitcode.com/gcw_E8NZtOkO/tools/releases/download/2.1.1.4/WorkTool.zip", UpdateVersion = "2.0.0.1", UpdateURL = "https://gitcode.com/gcw_E8NZtOkO/tools/releases/download/2.0.0.1/Update.zip" } }.Serialize());
                            break;

                        default:
                            break;
                    }
                }
            }
            catch (Exception ex)
            {
                new Modal.Config(this, "失败", ex.Message, TType.Error)
                {
                    OnButtonStyle = (id, btn) =>
                    {
                        btn.BackExtend = "135, #6253E1, #04BEFE";
                    },
                    CancelText = null,
                    OkText = "知道了"
                }.open();
            }
        }

        private void chatClear_btn_Click(object sender, EventArgs e)
        {
            chatList.Items.Clear();
        }
    }

    public class UserClient : NotifyProperty
    {
        private bool _check = false;

        public bool Check
        {
            get => _check;
            set
            {
                if (_check == value) return;
                _check = value;
                OnPropertyChanged();
            }
        }

        private string _ipAddress;

        public string IPAddress
        {
            get => _ipAddress;
            set
            {
                _ipAddress = value;
                OnPropertyChanged();
            }
        }

        private string _version;

        public string Version
        {
            get => _version;
            set
            {
                _version = value;
                OnPropertyChanged();
            }
        }

        private string _hostName;

        public string HostName
        {
            get => _hostName;
            set
            {
                _hostName = value;
                OnPropertyChanged();
            }
        }

        public CellLink[] Action => new CellLink[] {
            new CellButton("Dialog", "弹窗", TTypeMini.Error),
            new CellButton("Notification", "通知", TTypeMini.Error),
            new CellButton("BetaUpdate", "内测更新", TTypeMini.Error),
            new CellButton("ForcedUpdate", "强制更新", TTypeMini.Error)
        };
    }
}